#ifndef _PLAYER_H_
#define _PLAYER_H_

#ifdef _WIN32
#pragma once
#endif

/**
 * 09/03/12 - Steven Hartin - Original Creation
 */

class CPlayer;

#include <string>
#include <map>
#include <sstream>

#include <d3dx9.h>

#include "mapcontainer.h"

//#include "game/score.h"
#include "entity.h"
#include "movable_entity.h"
#include "entitycontainer.h"
#include "repeat.h"

#include "devicemanager.h"
#include "input.h"
#include "keyboard.h"

#include "buff.h"

#include "weapon.h"
#include "constants.h"

#include "map.h"

#include "menucontainer.h"
#include "ui.h"
#include "ui_sprite.h"
#include "ui_number.h"

using std::string;
using std::map;
using std::pair;
using std::stringstream;


typedef enum playerDirection
{
    PLAYER_DIRECTION_NONE  = 0,
    PLAYER_DIRECTION_UP    = 1 << 0,
    PLAYER_DIRECTION_DOWN  = 1 << 1,
    PLAYER_DIRECTION_LEFT  = 1 << 2,
    PLAYER_DIRECTION_RIGHT = 1 << 3
} DIRECTION_ID;

/*
    0000 
    0001
    0010
    0100
    1000
*/

class CPlayer : public CMovableEntity
{
public:

    CPlayer(float fX, float fY, float fZ, ENTITY_ID nPlayerId);
    ~CPlayer();

    CWeapon *getActiveWeapon() const;
    void setActiveWeapon(CWeapon *pWeapon);

    CWeapon* addWeapon(CWeapon* pWeapon);
    CWeapon* getWeapon(const ENTITY_ID &nId) const;
    bool hasWeapon(const ENTITY_ID &nId) const;

    const D3DXVECTOR3 &getViewVector() const;
    void getViewVector(float &fX, float &fY, float &fZ) const;
    void setViewVector(const D3DXVECTOR3 &vecView);
    void setViewVector(float fX, float fY, float fZ);

    CBuff *applyBuff(CBuff* pBuff);
    void removeBuff(CBuff *pBuff);
    void removeBuff(const ENTITY_ID &nBuffID);
    bool hasBuff(const ENTITY_ID &nId) const;
    CBuff *getBuff(const ENTITY_ID &nBuffId) const;

    ENTITY_ID getID() const;
    void setID(const ENTITY_ID &nID);

    float getSpeed() const;
    void setSpeed(float fSpeed);

    void setScore(int nScoreValue);
    void updateScore(int nScoreValue);
    int getScore() const;
    void incrementScore();
    void decrementScore();

    void handleKeyPress(const DEVICE_EVENT &params);

    bool isAlive() const;
    bool isDying() const;
    void kill();
    void respawn();


    void setAliveStatus(bool bAlive);

    virtual void reset();

    virtual void onCreate(CMap *pMap);

    void registerStat(const string &szStatName, signed long nInitialValue);
    signed long getStatValue(const string &szStatName) const;
    bool updateStatValue(const string &szStatName, long signed nAmount);
    bool setStatValue(const string &szStatName, signed long nInitialValue);
    void showStats();
    void hideStats();

private:
    ENTITY_ID m_nID;
    float m_fSpeed;

    D3DXVECTOR3 m_vecView;

    //CScore m_Score;
    CWeapon *m_pActiveWeapon;
    map<ENTITY_ID, CWeapon*> m_arrWeapons;
    vector<CBuff*> m_arrBuffs;

    CUISprite *m_pStatScreen;
    CUISprite *m_pScoreBorder;
    CUINumber *m_pScore;

    unsigned char m_chKeyUp;
    unsigned char m_chKeyDown;
    unsigned char m_chKeyLeft;
    unsigned char m_chKeyRight;
    unsigned char m_chKeyDropBomb;

    void walk(int direction);

    bool m_bAlive;
    bool m_bDying;

    CRepeat<void> m_MyRepeat;

    virtual void tick();

    int m_nMovement;
    bool isDirectionInStack(DIRECTION_ID direction);
    void removeFromStack(DIRECTION_ID direction);
};

namespace player{
    void handleKeyboard(const DEVICE_EVENT &params);
    void killPlayer(DELAY_PARAMS &params);
};

#endif